package com.hucsmn.studentms;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 作业题一：
 *  基于学生信息管理系统增加以下两个功能：
 *  a.自定义学号异常类和年龄异常类，并在该成员变量不合理时产生异常对象并抛出。
 *  b.当系统退出时将 List 集合中所有学生信息写入到文件中，当系统启动时读取文件中所 有学生信息到 List 集合中。
 */
public class ManageSystem {
    private static final File LOCATION = new File("./students.db");
    private static final Pattern REGEX_SEPARATOR = Pattern.compile("\\s+");

    private static Database db = new Database();

    public static void main(String[] args) {
        System.out.println("简易学生信息管理系统");
        System.out.println();

        if (LOCATION.isFile()) {
            loadDatabase(LOCATION);
            System.out.println();
        }

        help();

        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.print("学生信息管理系统> ");
            String[] cmd = parseLine(scanner.nextLine());
            if (cmd.length == 0) {
                help();
                return;
            }
            switch (cmd[0].toLowerCase()) {
                case "a":
                case "add":
                case "添加":
                    add(cmd);
                    break;
                case "d":
                case "del":
                case "delete":
                case "删除":
                    delete(cmd);
                    break;
                case "u":
                case "update":
                case "修改":
                    update(cmd);
                    break;
                case "g":
                case "lookup":
                case "get":
                case "查找":
                    get(cmd);
                    break;
                case "l":
                case "list":
                case "显示":
                    list(cmd);
                    break;
                case "c":
                case "clear":
                case "清空":
                    clear(cmd);
                    break;
                case "load":
                case "加载":
                    load(cmd);
                    break;
                case "save":
                case "保存":
                    save(cmd);
                    break;
                case "q":
                case "quit":
                case "exit":
                case "退出":
                    saveDatabase(LOCATION);
                    System.exit(0);
                    break;
                default:
                    help();
                    break;
            }
        }
    }

    private static void loadDatabase(File location) {
        try {
            System.out.println("正在从 '" + location.getPath() + "' 导入数据库...");
            db = Database.load(location);
        } catch (IOException e) {
            System.out.println("无法导入数据库：" + e);
        }
    }

    private static void saveDatabase(File location) {
        try {
            System.out.println("正在将数据库保存到 '" + location.getPath() + "' 文件中...");
            db.save(location);
        } catch (IOException e) {
            System.out.println("无法保存数据库：" + e);
        }
    }

    private static String[] parseLine(String line) {
        return REGEX_SEPARATOR.split(line.trim());
    }

    private static void help() {
        System.out.println("命令：");
        System.out.println("  添加 学号 姓名 年龄");
        System.out.println("  删除 学号");
        System.out.println("  修改 学号 [新的学号] 姓名 年龄");
        System.out.println("  修改 学号 新的学号");
        System.out.println("  查找 学号");
        System.out.println("  显示");
        System.out.println("  清空");
        System.out.println("  加载 [文件地址]");
        System.out.println("  保存 [文件地址]");
        System.out.println("  退出");
        System.out.println();
    }

    private static void add(String[] cmd) {
        Student student;
        try {
            student = Student.parse(cmd, 1, 3);
        } catch (IllegalStudentException e) {
            System.out.println("参数不正确：" + e.getMessage());
            return;
        }

        if (!db.add(student)) {
            System.out.println("学号重复！");
        } else {
            System.out.println("信息已录入。");
        }
    }

    private static void delete(String[] cmd) {
        int number;
        try {
            if (cmd.length != 2) {
                throw new IllegalArgumentException();
            }
            number = Integer.parseInt(cmd[1]);
        } catch (NumberFormatException ex) {
            System.out.println("学号必须是数字！");
            return;
        } catch (IllegalArgumentException ex) {
            System.out.println("参数不正确！");
            return;
        }

        if (!db.remove(number)) {
            System.out.println("学号不存在！");
        } else {
            System.out.println("信息已删除。");
        }
    }

    private static void update(String[] cmd) {
        int number;
        Student student;
        try {
            if (cmd.length == 3) {
                number = Integer.parseInt(cmd[1]);
                int newNumber = Integer.parseInt(cmd[2]);
                Student old = db.get(number);
                if (old == null) {
                    throw new NoSuchElementException();
                }
                student = new Student(newNumber, old.getName(), old.getAge());
            } else if (cmd.length == 4) {
                number = Integer.parseInt(cmd[1]);
                student = Student.parse(cmd, 1, 3);
            } else if (cmd.length == 5) {
                number = Integer.parseInt(cmd[1]);
                student = Student.parse(cmd, 2, 3);
            } else {
                throw new IllegalArgumentException();
            }
        } catch (NumberFormatException e) {
            System.out.println("学号和年龄必须是数字！");
            return;
        } catch (NoSuchElementException e) {
            System.out.println("学号不存在！");
            return;
        } catch (IllegalArgumentException e) {
            System.out.println("参数不正确！");
            return;
        }

        if (db.update(number, student) == null) {
            System.out.println("学号不存在或新的学号重复！");
        } else {
            System.out.println("信息已修改。");
        }
    }

    private static void get(String[] cmd) {
        int number;
        try {
            if (cmd.length != 2) {
                throw new IllegalArgumentException();
            }
            number = Integer.parseInt(cmd[1]);
        } catch (NumberFormatException ex) {
            System.out.println("学号必须是数字！");
            return;
        } catch (IllegalArgumentException ex) {
            System.out.println("参数不正确！");
            return;
        }

        Student student;
        if ((student = db.get(number)) == null) {
            System.out.println("学号不存在！");
        } else {
            System.out.println("学生信息为：");
            System.out.println(student);
            System.out.println();
        }
    }

    private static void list(String[] cmd) {
        if (cmd.length != 1) {
            System.out.println("不需要提供参数！");
            return;
        }

        System.out.println("已录入的学生信息：");
        for (Student student : db) {
            System.out.println(student);
        }
        System.out.println();
    }

    private static void clear(String[] cmd) {
        if (cmd.length != 1) {
            System.out.println("不需要提供参数！");
            return;
        }

        db = new Database();
        System.out.println("数据已清空。");
        System.out.println();
    }

    private static void load(String[] cmd) {
        File location;
        if (cmd.length == 1) {
            location = LOCATION;
        } else if (cmd.length == 2) {
            location = new File(cmd[1]);
            if (!location.isFile()) {
                System.out.println("文件不存在！");
                return;
            }
        } else {
            System.out.println("不需要提供多余参数！");
            return;
        }

        if (db.size() > 0) {
            System.out.println("数据库将被覆盖。");
        }

        loadDatabase(location);
        System.out.println("数据已加载。");
        System.out.println();
    }

    private static void save(String[] cmd) {
        File location;
        if (cmd.length == 1) {
            location = LOCATION;
        } else if (cmd.length == 2) {
            location = new File(cmd[1]);
        } else {
            System.out.println("不需要提供多余参数！");
            return;
        }

        if (location.isFile()) {
            System.out.println("原本的数据库文件将被覆盖。");
        }

        saveDatabase(location);
        System.out.println("数据已保存。");
        System.out.println();
    }
}
